/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.persistencia.dao.impl;

import com.persistencia.dao.EntidadDao;
import com.util.JPAutil;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaQuery;

/**
 *
 * @author kenny
 */
public class EntidadDaoImpl<E> implements EntidadDao<E> {
    
        EntityManagerFactory emf;
	EntityManager em;
	JPAutil jpaUtil;
	
	protected E instance;	
	private Class<E> entityClass;
	
	public EntidadDaoImpl(){
		jpaUtil=new JPAutil();
		emf=jpaUtil.getEmf();
		em=jpaUtil.getEm();
	}
	
	public EntityManager getEntityManager() {
		return em;
	}
    @Override
    public void registrar(E e) throws Exception {
        em.getTransaction().begin();
        em.persist(e);
        em.getTransaction().commit();
    }

    @Override
    public void actualizar(E e) throws Exception {
            em = getEntityManager();
            em.getTransaction().begin();
            em.merge(e);
            em.getTransaction().commit();
    }

    @Override
    public void eliminar(Object id) throws Exception {
        E e = obtenerPorId(id);
	getEntityManager().getTransaction().begin();
	getEntityManager().remove(e);
	getEntityManager().getTransaction().commit();
    }

    @Override
    public E obtenerPorId(Object id) throws Exception {
        return (E) getEntityManager().find(getEntityClass(), id);
    }

    @Override
    public List<E> obtenerLista() throws Exception {
        
        /*System.out.println("Nombre"+getEntityClass().getName());
        String hql = "select e from " + getEntityClass().getName()+" e";
	Query query = getEntityManager().createQuery(hql);
	return query.getResultList();*/
        try {
            System.out.println("Entidad"+getEntityClass());
            System.out.println("Entidad"+getEntityClass().getClass());
            //System.out.println("Docente.class "+Docente.class);
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(getEntityClass()));
            //cq.select(cq.from(Docente.class));
            Query q = em.createQuery(cq);
            return q.getResultList();
        } finally {
            
        }
        //List<Docente> a = new A;
        //return (List<E>) a;
    }
    
    public Class<E> getEntityClass() throws Exception {
		if (entityClass == null) {
			Type type = getClass().getGenericSuperclass();
			if (type instanceof ParameterizedType) {
				ParameterizedType paramType = (ParameterizedType) type;
				if (paramType.getActualTypeArguments().length == 2) {
					if (paramType.getActualTypeArguments()[1] instanceof TypeVariable) {
						throw new IllegalArgumentException(
								"No se puede obtener clase mediante reflection");
					} else {
						entityClass = (Class<E>) paramType
								.getActualTypeArguments()[1];
					}
				} else {
					entityClass = (Class<E>) paramType.getActualTypeArguments()[0];
				}
			} else {
				throw new Exception(
						"No se puede obtener clase mediante reflection");
			}
		}
		return entityClass;
    }
    
    
    
}
